#!/usr/bin/env node
// deploy-all.js - 批量部署多个微前端应用的脚本

import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs';
import { createInterface } from 'readline';

// 获取当前文件的目录路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 命令行参数解析
const args = process.argv.slice(2);
const skipBuild = args.includes('--skip-build');
const envArg = args.find(arg => arg.startsWith('--env='));
const env = envArg ? envArg.split('=')[1] : 'production';
const parallel = args.includes('--parallel');
const specificApps = args.filter(arg => !arg.startsWith('--'));

// 获取可部署的应用列表
function getAvailableApps() {
  const appsDir = path.resolve(__dirname, './apps');
  
  if (!fs.existsSync(appsDir)) {
    console.error('错误: apps目录不存在');
    return [];
  }
  
  return fs.readdirSync(appsDir)
    .filter(app => {
      const appDir = path.join(appsDir, app);
      return fs.statSync(appDir).isDirectory() && 
             fs.existsSync(path.join(appDir, 'package.json'));
    });
}

// 询问用户选择要部署的应用
async function promptForApps(availableApps) {
  const rl = createInterface({
    input: process.stdin,
    output: process.stdout
  });

  return new Promise((resolve) => {
    console.log('可部署的应用:');
    availableApps.forEach((app, index) => {
      console.log(`[${index + 1}] ${app}`);
    });
    console.log('[0] 全部应用');
    
    rl.question('请选择要部署的应用 (多个应用用逗号分隔，如 1,3,5): ', (answer) => {
      rl.close();
      
      if (answer.trim() === '0') {
        resolve(availableApps);
        return;
      }
      
      const selectedIndices = answer.split(',')
        .map(s => parseInt(s.trim(), 10))
        .filter(n => !isNaN(n) && n > 0 && n <= availableApps.length);
      
      if (selectedIndices.length === 0) {
        console.log('没有选择有效的应用，将部署所有应用');
        resolve(availableApps);
        return;
      }
      
      const selectedApps = selectedIndices.map(i => availableApps[i - 1]);
      resolve(selectedApps);
    });
  });
}

// 构建单个应用
async function buildApp(appName) {
  if (skipBuild) {
    console.log(`跳过构建 ${appName}`);
    return true;
  }
  
  console.log(`正在构建 ${appName}...`);
  try {
    execSync(`pnpm --filter ${appName} build`, { stdio: 'inherit' });
    console.log(`${appName} 构建成功`);
    return true;
  } catch (error) {
    console.error(`构建 ${appName} 失败:`, error);
    return false;
  }
}

// 部署单个应用
async function deployApp(appName) {
  console.log(`正在部署 ${appName}...`);
  try {
    execSync(`node deploy-cdn.js ${appName}`, { stdio: 'inherit' });
    console.log(`${appName} 部署成功`);
    return true;
  } catch (error) {
    console.error(`部署 ${appName} 失败:`, error);
    return false;
  }
}

// 确保配置文件存在
async function ensureConfig() {
  const envFile = path.resolve(__dirname, './.env');
  
  if (!fs.existsSync(envFile)) {
    console.log('未找到全局配置文件，将创建默认配置...');
    
    try {
      // 运行初始化命令
      execSync(`node deploy-cdn.js init`, { stdio: 'inherit' });
    } catch (error) {
      console.error('创建配置文件失败:', error);
      process.exit(1);
    }
  }
}

// 主函数
async function main() {
  console.log('=== 微前端批量部署工具 ===');
  console.log(`环境: ${env}`);
  console.log(`构建模式: ${skipBuild ? '跳过构建' : '先构建后部署'}`);
  console.log(`部署模式: ${parallel ? '并行部署' : '串行部署'}`);
  
  // 确保配置文件存在
  await ensureConfig();
  
  // 获取可部署的应用
  const availableApps = getAvailableApps();
  
  if (availableApps.length === 0) {
    console.error('没有找到可部署的应用');
    process.exit(1);
  }
  
  // 确定要部署的应用列表
  let appsToDeployNames;
  
  if (specificApps.length > 0) {
    // 验证指定的应用是否存在
    const invalidApps = specificApps.filter(app => !availableApps.includes(app));
    if (invalidApps.length > 0) {
      console.error(`错误: 以下应用不存在: ${invalidApps.join(', ')}`);
      console.log('可用的应用:', availableApps.join(', '));
      process.exit(1);
    }
    appsToDeployNames = specificApps;
  } else {
    // 交互式选择应用
    appsToDeployNames = await promptForApps(availableApps);
  }
  
  console.log(`将部署以下应用: ${appsToDeployNames.join(', ')}`);
  
  // 记录结果
  const results = {
    success: [],
    failed: []
  };
  
  // 部署应用
  if (parallel) {
    // 并行构建和部署
    console.log('开始并行构建和部署...');
    
    // 先并行构建所有应用
    if (!skipBuild) {
      console.log('正在并行构建所有应用...');
      const buildPromises = appsToDeployNames.map(async (appName) => {
        const success = await buildApp(appName);
        return { appName, success };
      });
      
      const buildResults = await Promise.all(buildPromises);
      const failedBuilds = buildResults.filter(r => !r.success).map(r => r.appName);
      
      if (failedBuilds.length > 0) {
        console.error(`以下应用构建失败: ${failedBuilds.join(', ')}`);
        results.failed.push(...failedBuilds);
        // 从部署列表中移除构建失败的应用
        appsToDeployNames = appsToDeployNames.filter(app => !failedBuilds.includes(app));
      }
    }
    
    // 并行部署所有构建成功的应用
    console.log('正在并行部署应用...');
    const deployPromises = appsToDeployNames.map(async (appName) => {
      const success = await deployApp(appName);
      return { appName, success };
    });
    
    const deployResults = await Promise.all(deployPromises);
    
    deployResults.forEach(({ appName, success }) => {
      if (success) {
        results.success.push(appName);
      } else {
        results.failed.push(appName);
      }
    });
  } else {
    // 串行构建和部署
    console.log('开始串行构建和部署...');
    
    for (const appName of appsToDeployNames) {
      console.log(`\n=== 处理应用: ${appName} ===`);
      
      // 构建
      if (!skipBuild) {
        const buildSuccess = await buildApp(appName);
        if (!buildSuccess) {
          console.error(`跳过 ${appName} 的部署，因为构建失败`);
          results.failed.push(appName);
          continue;
        }
      }
      
      // 部署
      const deploySuccess = await deployApp(appName);
      if (deploySuccess) {
        results.success.push(appName);
      } else {
        results.failed.push(appName);
      }
    }
  }
  
  // 打印结果摘要
  console.log('\n=== 部署结果摘要 ===');
  console.log(`成功: ${results.success.length} 个应用`);
  if (results.success.length > 0) {
    console.log(`- ${results.success.join('\n- ')}`);
  }
  
  console.log(`失败: ${results.failed.length} 个应用`);
  if (results.failed.length > 0) {
    console.log(`- ${results.failed.join('\n- ')}`);
    process.exit(1);
  }
  
  console.log('\n所有应用部署完成!');
}

// 执行主函数
main().catch(error => {
  console.error('部署失败:', error);
  process.exit(1);
}); 